package com.yt.order.provider.service.impl;

import com.yt.order.api.interfaces.OrderNumberService;
import com.yt.order.api.model.OrderNumber;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

public class OrderNumberManager {
	//订单来源
	public static enum OrderFrom {
		INTERNAL("内部", 0),
		Agent("代理商", 1);
		private String fromName;
		private int value;

		OrderFrom(String fromName, int value) {
			this.fromName = fromName;
			this.value = value;
		}

		public String getFromName() {
			return fromName;
		}

		public void setFromName(String fromName) {
			this.fromName = fromName;
		}

		public int getValue() {
			return value;
		}

		public void setValue(int value) {
			this.value = value;
		}
	}

	private static SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");

	private static DecimalFormat df = new DecimalFormat("00000");
	/**
	 * 单例
	 */
	private static OrderNumberManager manager;

	/**
	 * 当前id
	 */
	private long currentID;

	/**
	 * 最大ID
	 */
	private long maxID;

	/**
	 * 一次性缓存个数
	 */
	private int blockSize = 20;

	private String currentDateStr;

	/**
	 * 初始化实例
	 */
	private static OrderNumberManager getInstance() {
		if (manager == null) {
			manager = new OrderNumberManager();
		}
		return manager;
	}

	/**
	 * 构造函数
	 */
	private OrderNumberManager() {
		currentID = 1L;
		maxID = 0L;
	}

	public static String nextOrderNumber(int orderFrom, int orderType, OrderNumberService orderNumberService) {
		return getInstance().nextUniqueOrderNumber(null, orderFrom, orderType, orderNumberService);
	}

	public static String nextOrderNumber(Date date, int orderFrom, int orderType, OrderNumberService orderNumberService) {
		return getInstance().nextUniqueOrderNumber(date, orderFrom, orderType, orderNumberService);
	}

	/**
	 * 获取一个订单编号ID
	 *
	 * @return long
	 */
	private synchronized String nextUniqueOrderNumber(Date date, int orderFrom, int orderType, OrderNumberService orderNumberService) {
		String dateString = sdf.format(date == null ? new Date() : date);
		if (!dateString.equals(currentDateStr) || currentID >= maxID) {
			getNextBlock(date, blockSize, orderNumberService);
			currentDateStr = dateString;
		}
		long id = currentID;
		currentID++;

		return "00" + currentDateStr + orderFrom + orderType + df.format(id);
	}

	private String getTodayDate(Date date) {
		if (date == null) {
			date = new Date();
		}
		return sdf.format(date);
	}

	/**
	 * ID申请逻辑方法
	 *
	 * @param count int
	 */
	private void getNextBlock(Date date, int count, OrderNumberService orderNumberService) {
		if (count == 0) {
			System.out
					.println("Failed at last attempt to obtain an ID, aborting...");
			return;
		}
		Long todayDate = Long.parseLong(getTodayDate(date));
		OrderNumber orderNumber = orderNumberService.get(todayDate);
		if (orderNumber != null) {
			orderNumber.setOrderNumberIndex(orderNumber.getOrderNumberIndex() + count);
			orderNumberService.update(orderNumber);
			currentID = orderNumber.getOrderNumberIndex();
			maxID = currentID + count;
		} else {
			orderNumber = new OrderNumber();
			orderNumber.setOrderDate(todayDate);
			orderNumber.setOrderNumberIndex((long) count + 1);
			orderNumberService.insert(orderNumber);
			currentID = 1;
			maxID = currentID + count;
		}
	}

}